package insight.web.controllers;

import insight.miescor.annotations.Constants;
import insight.miescor.db.DBManager;
import insight.miescor.opp.domain.Assignment;
import insight.miescor.opp.domain.AssignmentGrid;
import insight.miescor.opp.domain.CodeValue;
import insight.miescor.opp.domain.OppReport;
import insight.miescor.opp.domain.Opportunity;
import insight.miescor.opp.domain.Review;
import insight.miescor.opp.domain.Roles;
import insight.miescor.opp.domain.WorkflowRole;
import insight.web.delegates.AjaxJSONDelegate;
import insight.web.delegates.PrimaveraDelegate;
import insight.web.delegates.PrimaveraDelegate.ProjectTeam;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.python.modules.jarray;
import org.sormula.SormulaException;
import org.sormula.Table;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.primavera.ServerException;
import com.primavera.common.value.ObjectId;
import com.primavera.integration.client.Session;
import com.primavera.integration.client.bo.BusinessObjectException;
import com.primavera.integration.client.bo.object.Project;
import com.primavera.integration.network.NetworkException;

@Controller
public class AddOpportunityController extends GenericController {
	@Autowired
	private DBManager dbManager;

	@RequestMapping("/loadOBSUser.htm")
	public ModelAndView loadOBSUsers(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		List<CodeValue> obsUser = PrimaveraDelegate.getOBSList(helper
				.getSession());
		Gson gson = new Gson();
		String userList = gson.toJson(obsUser);
		AjaxJSONDelegate.setTextResponse(userList, response);
		return null;
	}

	@RequestMapping("/ResourceDetails.htm")
	public ModelAndView resouceDetails(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav;
		String opportunityId = request.getParameter("opportunityId");
		String assignmentId = request.getParameter("assId");
		String prjObjId = request.getParameter("prjObjId");
		int stepId = Assignment
				.getStepId(dbManager.getDatabase(), assignmentId);
		if (request.getSession().getAttribute("userName") == null) {
			mav = new ModelAndView("errorPage");
			mav.addObject("ErrorMessage", "Session Expired!");
			mav.addObject("Exception", "Session expired please login again!");
			return mav;
		}
		mav = new ModelAndView("ResourceDetails");
		mav.addObject("opportunityId", opportunityId);
		mav.addObject("prjObjId", prjObjId);
		mav.addObject("assignmentId", assignmentId);
		mav.addObject("stepId", stepId);
		mav.addObject(request.getSession().getAttribute("userName"));
		return mav;
	}

	@RequestMapping("/getResourceDetails.htm")
	public ModelAndView getResourceDetails(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String prjObjId = request.getParameter("prjObjId");

		Project project = Project.load(helper.getSession(), new String[] {
				"Id", "Name", "LocationObjectId", "LocationName",
				"SummaryLevel" }, new ObjectId(Integer.parseInt(prjObjId)));
		List<ProjectTeam> projectTeam = PrimaveraDelegate.loadProjectTeam(
				helper.getSession(), project);
		Gson gson = new Gson();
		String projectTeamTxt = gson.toJson(projectTeam);
		AjaxJSONDelegate.setTextResponse(projectTeamTxt, response);
		return null;
	}

	@RequestMapping("/ViewOpportunity.htm")
	public ModelAndView viewOpportunity(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav;
		String opportunityId = request.getParameter("opportunityId");
		String assignmentId = request.getParameter("assId");
		String prjObjId = request.getParameter("prjObjId");
		int stepId = Assignment
				.getStepId(dbManager.getDatabase(), assignmentId);
		if (request.getSession().getAttribute("userName") == null) {
			mav = new ModelAndView("errorPage");
			mav.addObject("ErrorMessage", "Session Expired!");
			mav.addObject("Exception", "Session expired please login again!");
			return mav;
		}
		mav = new ModelAndView("ViewOpportunity");
		mav.addObject("opportunityId", opportunityId);
		mav.addObject("prjObjId", prjObjId);
		mav.addObject("assignmentId", assignmentId);
		mav.addObject("stepId", stepId);
		mav.addObject(request.getSession().getAttribute("userName"));
		return mav;
	}

	@RequestMapping("/getCompleteOpportunity.htm")
	public ModelAndView getCompleteOpportunity(HttpServletRequest request,
			HttpServletResponse response) throws NumberFormatException,
			ServerException, NetworkException {
		String prjObjId = request.getParameter("prjObjId");
		String oppId = request.getParameter("oppId");
		Session session = helper.getSession();

		Project project = null;
		try {
			project = Project.load(session, new String[] { "Id", "Name",
					"LocationObjectId", "LocationName" },
					new ObjectId(Integer.parseInt(prjObjId)));
		} catch (BusinessObjectException e3) {
			AjaxJSONDelegate.reportError(response, "Could not load Project ["
					+ prjObjId + "] from Primavera. " + e3.getMessage(), null);
			e3.printStackTrace();
		}
		// Opportunity oppObj = new Opportunity(helper.getSession(),
		// project,dbManager.getDatabase());

		if (project == null) {
			AjaxJSONDelegate.reportError(response, "Could not found project ["
					+ prjObjId + "] in Primavera.", null);
			System.out.println("Could not found project");
			return null;
		}

		Opportunity oppObj = null;
		try {
			oppObj = Opportunity.getOpportunityById(dbManager.getDatabase(),
					oppId);
		} catch (SormulaException e2) {
			AjaxJSONDelegate.reportError(response,
					"Could not found Opportunity [" + prjObjId
							+ "] in database. " + e2.getMessage(), null);
			return null;
		}

		try {
			oppObj.loadP6Data(session, project);
			String notebookContract = PrimaveraDelegate
					.getProjectNotebookContent(session, project,
							Constants.ProjectFields.NOTEBOOK_CONTRACT_VALUE);
			oppObj.setContractValueNotebookText(notebookContract);
		} catch (BusinessObjectException e2) {
			e2.printStackTrace();
			return null;
		}

		Review review = null;
		try {
			review = new Review(session, project);
		} catch (BusinessObjectException e2) {
			e2.printStackTrace();
		}

		List<Assignment> assList = null;
		try {
			assList = Assignment.getAssignmentDetailByOppId(
					dbManager.getDatabase(), oppObj.getId());
			String userPersonalName = "";
			for (Assignment assObj : assList) {
				if (assObj.getUserId() != null && assObj.getUserId().equals("")) {
					try {
						userPersonalName = PrimaveraDelegate.getUserName(
								helper.getSession(), assObj.getUserId());
					} catch (Exception e) {
						e.printStackTrace();
					}
					assObj.setUserId(userPersonalName);

				}
			}

		} catch (Exception e1) {
			e1.printStackTrace();
		}

		Gson gson = new Gson();

		String oppJson = gson.toJson(oppObj);
		String reviewJson = gson.toJson(review);
		String assJson = gson.toJson(assList);

		JSONObject jObj = new JSONObject();

		try {
			jObj.put("opportunity", new JSONObject(oppJson))
					.put("review", new JSONObject(reviewJson))
					.put("oppStatus", new JSONArray(assJson))
					.put("oppCurrentStatus", oppObj.getStatus());
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println(oppJson);
		AjaxJSONDelegate.setResponse(jObj, response);
		return null;
	}

	@RequestMapping("/home.htm")
	public ModelAndView loadHome(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav;
		String userId = request.getParameter("userId");
		if (userId != "") {
			mav = new ModelAndView("home");
			mav.addObject("userId", userId);
			mav.addObject("projectType", Constants.ProjectFields.PROJECT_TYPE);
			mav.addObject("market", Constants.ProjectFields.MARKET);
			mav.addObject("portfolio", Constants.ProjectFields.PORTFOLIO);
			String userName = PrimaveraDelegate.getUserName(
					helper.getSession(), userId);
			request.getSession().setAttribute("userId", userId);
			request.getSession().setAttribute("userName", userName);
		} else {
			mav = new ModelAndView("errorPage");
			mav.addObject("ErrorMessage", "Session Expired!");
			mav.addObject("Exception", "Session expired please login again!");
		}
		return mav;
	}

	@RequestMapping("/ActionItems.htm")
	public ModelAndView actionItemsHome(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView("ActionItems");
		String userId = request.getParameter("userId");

		if (userId != "") {
			String userName = PrimaveraDelegate.getUserName(
					helper.getSession(), userId);
			request.getSession().setAttribute("userId", userId);
			request.getSession().setAttribute("userName", userName);
		}

		mav.addObject("userId", userId);
		Table<Roles> role = dbManager.getDatabase().getTable(Roles.class);
		Roles roleObj = role.select(userId);
		if (roleObj != null)
			mav.addObject("type", roleObj.getRole());
		return mav;
	}

	@RequestMapping("/listActionItems.htm")
	public ModelAndView listActionItems(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String userId = request.getParameter("userId");
		List<String> userRoles = PrimaveraDelegate.getUserRoles(userId,
				dbManager.getDatabase());

		String filter = request.getParameter("filter");

		List<AssignmentGrid> selOppurtunity = null;
		if (filter.equalsIgnoreCase("Claimed")) {
			selOppurtunity = dbManager.getClaimedAssignmentList(
					new String[] { "Claimed" },
					userRoles.toArray(new String[userRoles.size()]), userId);
		} else {
			selOppurtunity = dbManager.getAssignmentList(new String[] {
					"Pending", "Claimed" },
					userRoles.toArray(new String[userRoles.size()]));
		}

		JSONArray jArray = new JSONArray();
		for (AssignmentGrid item : selOppurtunity) {
			if (item.getStepId() == 4) {
				if (item.getUserId().equals(userId))
					jArray.put(item.getJson());
			} else
				jArray.put(item.getJson());
		}

		AjaxJSONDelegate.setResponse(jArray, response);
		return null;
	}

	@RequestMapping("/AddOpportunity.htm")
	public ModelAndView addOpportunity(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView("AddOpportunity");
		String market = request.getParameter("market");
		String projectType = request.getParameter("projectType");
		String portfolio = request.getParameter("portfolio");
		String portfolioName = request.getParameter("portfolioName");
		String userId = request.getParameter("userId");

		mav.addObject("market", market);
		mav.addObject("projectType", projectType);
		mav.addObject("portfolio", portfolio);
		mav.addObject("portfolioName", portfolioName);
		mav.addObject("userId", userId);

		return mav;
	}

	@RequestMapping("/saveOpportunity.htm")
	public ModelAndView saveOpportunity(HttpServletRequest request,
			HttpServletResponse response) throws JSONException {
		JSONObject oppJson = null;
		try {
			oppJson = readJSON(request);
		} catch (Exception e) {
			AjaxJSONDelegate.setResponse(new JSONObject().put("success", false)
					.put("message", e.getMessage()), response);
			return null;
		}
		System.out.println(oppJson);

		if (request.getSession().getAttribute("userName") == null) {
			AjaxJSONDelegate.setResponse(new JSONObject().put("success", false)
					.put("message", "Session expired, please login again!"),
					response);
			return null;
		}

		String userName = request.getSession().getAttribute("userName")
				.toString();

		Gson gson = new GsonBuilder().setDateFormat("MM/dd/yyyy").create();
		Opportunity oppObj = gson.fromJson(oppJson.toString(),
				Opportunity.class);
		if (oppObj.getMarket() != null)
			oppObj.setDbMarket(oppObj.getMarket().getId());
		if (oppObj.getPortfolio() != null)
			oppObj.setDbPortfolio(oppObj.getPortfolio().getId());
		if (oppObj.getProjectType() != null)
			oppObj.setDbProjectType(oppObj.getProjectType().getId());
		try {
			oppObj.generateId(dbManager.getDatabase(), helper.getSession());

			oppObj.save(dbManager.getDatabase(), helper.getSession(), false,
					userName);
			AjaxJSONDelegate.setResponse(new JSONObject().put("success", true)
					.put("message", "Opportunity saved successfully."),
					response);
		} catch (Exception e) {
			AjaxJSONDelegate.setResponse(new JSONObject().put("success", false)
					.put("message", e.getMessage()), response);
		}

		return null;
	}

	@RequestMapping("/MapRole.htm")
	public ModelAndView mapRole(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView("MapRole");

		// String userId = request.getParameter("userId");
		// if (userId != "") {
		// String userName = PrimaveraDelegate.getUserName(
		// helper.getSession(), userId);
		// request.getSession().setAttribute("userId", userId);
		// request.getSession().setAttribute("userName", userName);
		// }

		String userId = request.getParameter("userId");
		if (userId != null && userId.equals("admin")) {
			String userName = PrimaveraDelegate.getUserName(
					helper.getSession(), userId);
			request.getSession().setAttribute("userId", userId);
			request.getSession().setAttribute("userName", userName);
			mav.addObject("userId", userId);
			return mav;
		}

		return null;
	}

	@RequestMapping("/loadUsers.htm")
	public ModelAndView loadUsers(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		JSONArray jArray = new JSONArray();
		if (request.getParameter("showAll") != null
				&& request.getParameter("showAll").equalsIgnoreCase("NO")) {
			ArrayList<String> list = new ArrayList<String>();
			Table<Roles> role = dbManager.getDatabase().getTable(Roles.class);
			List<Roles> roles = role.selectAll();
			for (Roles r : roles) {
				if (!list.contains(r.getUserid())) {
					list.add(r.getUserid());
					jArray.put(new JSONObject().put("id", r.getUserid()).put(
							"text",
							r.getUserid()
									+ " [ "
									+ PrimaveraDelegate.getUserName(
											helper.getSession(), r.getUserid())
									+ " ] "));
				}
			}
		} else {
			Map<String, String> userList = PrimaveraDelegate.getAllUsers(helper
					.getSession());
			for (Map.Entry<String, String> entry : userList.entrySet()) {
				jArray.put(new JSONObject().put("id", entry.getKey()).put(
						"text",
						entry.getKey() + " [ " + entry.getValue() + " ] "));
			}
		}
		AjaxJSONDelegate.setResponse(jArray, response);
		return null;
	}

	@RequestMapping("/listRole.htm")
	public ModelAndView listRole(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String userId = request.getParameter("userId");
		// Table<Roles> role = dbManager.getDatabase().getTable(Roles.class);
		Table<WorkflowRole> role = dbManager.getDatabase().getTable(
				WorkflowRole.class);
		// List<Roles> allroles=role.selectAll();
		List<WorkflowRole> allroles = role.selectAll();
		Set<String> distinctRole = new HashSet<String>();

		for (WorkflowRole r : allroles) {
			distinctRole.add(r.getRole());
		}

		List<Roles> selRoles = Roles.getRolesByUser(dbManager.getDatabase(),
				userId);

		JSONArray jArray = new JSONArray();
		for (String d : distinctRole) {
			for (Roles r : selRoles) {
				if (d.equalsIgnoreCase(r.getRole())
						&& userId.equals(r.getUserid())) {
					jArray.put(new JSONObject()
							.put("name", r.getRole())
							.put("permitted", true)
							.put("description", getRoleDescription(r.getRole())));
				}
			}
		}
		for (String d : distinctRole) {
			boolean exists = false;
			for (Roles r : selRoles) {
				if ((d.equals(r.getRole()))) {
					exists = true;
				}
			}
			if (exists == false) {
				jArray.put(new JSONObject().put("name", d)
						.put("permitted", false)
						.put("description", getRoleDescription(d)));
			}
		}
		AjaxJSONDelegate.setResponse(jArray, response);
		return null;
	}

	private String getRoleDescription(String roleName) throws SormulaException {
		return WorkflowRole.getRolesDescription(dbManager.getDatabase(),
				roleName);
	}

	@RequestMapping("/UpdateRole.htm")
	public ModelAndView updateRole(HttpServletRequest request,
			HttpServletResponse response) throws JSONException,
			SormulaException {
		JSONObject oppJson = null;
		try {
			oppJson = readJSON(request);
		} catch (Exception e) {
			return null;
		}
		try {
			Table<Roles> role = dbManager.getDatabase().getTable(Roles.class);
			String targetUser = oppJson.getString("targetUser");
			String roles[] = oppJson.getString("roles").split(":");
			List<Roles> oldRoles = Roles.getRolesByUser(
					dbManager.getDatabase(), targetUser);
			if (oldRoles != null && oldRoles.size() > 0)
				role.deleteAll(oldRoles);
			if (!roles[0].equals("")) {
				for (String r : roles) {
					Roles newRole = new Roles();
					newRole.setId(Roles.generateId(dbManager.getDatabase()));
					newRole.setRole(r.equalsIgnoreCase("initiator") == true ? "initiator"
							: r);
					newRole.setUserid(targetUser);
					role.insert(newRole);
				}
			}
			AjaxJSONDelegate.setResponse(new JSONObject().put("success", true)
					.put("message", "Roles Updated successfully."), response);
		} catch (Exception e) {
			AjaxJSONDelegate.setResponse(
					new JSONObject().put("success", false).put("message",
							"Unable to update Roles. Please try again."),
					response);
		}
		return null;
	}

	@RequestMapping("/OppReview.htm")
	public ModelAndView GetReviewView(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String type = request.getParameter("type");
		String userId = request.getParameter("userId");
		String opportunityId = request.getParameter("opportunityId");
		String prjObjId = request.getParameter("prjObjId");
		String assignmentId = request.getParameter("assignmentId");

		ModelAndView mav = null;
		if (type == null)
			throw new Exception("Review type missing in the request.");

		if (type.equalsIgnoreCase("financial")) {
			mav = new ModelAndView("FinancialReview");
		} else if (type.equalsIgnoreCase("capability")) {
			mav = new ModelAndView("CapabilityReview");
		} else if (type.equalsIgnoreCase("legal")) {
			mav = new ModelAndView("LegalReview");
		} else if (type.equalsIgnoreCase("strategic")) {
			mav = new ModelAndView("StrategicReview");
		} else if (type.equalsIgnoreCase("opportunity")) {
			mav = new ModelAndView("AddOpportunity");
		} else if (type.equalsIgnoreCase("prc")) {
			mav = new ModelAndView("PMAssignment");
		} else if (type.equalsIgnoreCase("prc")) {
			mav = new ModelAndView("PMAssignment");
		} else if (type.equalsIgnoreCase("BD")) {
			mav = new ModelAndView("BD");
		}

		else {
			mav = new ModelAndView("errorPage");
			mav.addObject("ErrorMessage", "Invalid View Type!");
			mav.addObject("Exception", "Unexpected review type " + type + ".");

		}
		mav.addObject("userId", userId);
		mav.addObject("opportunityId", opportunityId);
		mav.addObject("prjObjId", prjObjId);
		mav.addObject("assignmentId", assignmentId);
		return mav;
	}

	@RequestMapping("/saveReviewData.htm")
	public ModelAndView saveReviewData(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		JSONObject oppObj = readJSON(request);
		System.out.println(oppObj);

		if (request.getSession().getAttribute("userName") == null) {
			AjaxJSONDelegate.setResponse(new JSONObject().put("success", false)
					.put("message", "Session expired, please login again!"),
					response);
			return null;
		}

		String userName = request.getSession().getAttribute("userName")
				.toString();
		Gson gson = new Gson();

		Review review = gson.fromJson(oppObj.toString(), Review.class);
		PrimaveraDelegate.saveReview(helper.getSession(), review, userName);

		AjaxJSONDelegate.setResponse(
				new JSONObject().put("success", true).put("message",
						"Review saved successfully."), response);
		return null;
	}

	@RequestMapping("/getViewData.htm")
	public ModelAndView getViewData(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String prjObjId = request.getParameter("prjObjId");
		Gson gson = new Gson();
		String jsonData = "";
		Project project = Project.load(helper.getSession(), new String[] {
				"Id", "Name" }, new ObjectId(Integer.parseInt(prjObjId)));

		Review review = new Review(helper.getSession(), project);
		jsonData = gson.toJson(review);
		System.out.println(jsonData);

		AjaxJSONDelegate.setTextResponse(jsonData, response);

		return null;
	}

	@RequestMapping("/getOpportunityViewData.htm")
	public ModelAndView getOpportunityViewData(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String prjObjId = request.getParameter("prjObjId");
		Gson gson = new Gson();
		String jsonData = "";
		Opportunity opprtunity;
		if (prjObjId != null && !prjObjId.equals("")) {
			Project project = Project.load(helper.getSession(), new String[] {
					"Id", "Name", "LocationObjectId", "LocationName" },
					new ObjectId(Integer.parseInt(prjObjId)));

			opprtunity = new Opportunity(helper.getSession(), project);

		} else {
			opprtunity = new Opportunity();
		}
		jsonData = gson.toJson(opprtunity);
		AjaxJSONDelegate.setTextResponse(jsonData, response);
		return null;
	}

	@RequestMapping("/getViewName.htm")
	public ModelAndView getViewName(HttpServletRequest request,
			HttpServletResponse response) {
		// String userId = request.getParameter("userId");
		// String id = request.getParameter("assignmentId");

		// Assignment
		// assObj=Assignment.getAssignmentById(dbManager.getDatabase(), id);

		return null;
	}

	@RequestMapping("/oppReport.htm")
	public ModelAndView getOppReport(HttpServletRequest request,
			HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("opportunityReport");
		return mav;
	}

	@RequestMapping("/pivotChart.htm")
	public ModelAndView getPivotChart(HttpServletRequest request,
			HttpServletResponse response) {
		ModelAndView mav = new ModelAndView("pivotChart");
		return mav;
	}

	@RequestMapping("/pivotChart1.htm")
	public ModelAndView getPivotChart1(HttpServletRequest request,
			HttpServletResponse response) throws JSONException {
		ModelAndView mav = new ModelAndView("pivotChart1");

		return mav;
	}

	@RequestMapping("/getPivotData.htm")
	public ModelAndView getPivotData(HttpServletRequest request,
			HttpServletResponse response) {
		try {

			List<Opportunity> oppList = null;
			try {
				oppList = Opportunity.loadAll(dbManager.getDatabase());
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			if (oppList.size() == 0)
				return null;

			// List<OppReport> lstReport = new ArrayList();
			JSONArray jAry = new JSONArray();
			for (Opportunity opp : oppList) {
				Project project;
				project = Project.load(helper.getSession(), new String[] {
						"Id", "Name", "LocationObjectId", "LocationName" },
						new ObjectId(opp.getProjectId()));
				if (project != null) {
					opp.loadP6Data(helper.getSession(), project);
					OppReport oppReport = new OppReport(helper.getSession(),
							project, opp);
					try {
						jAry.put(oppReport.toJson());
					} catch (JSONException e) {
						e.printStackTrace();
					}
				}
			}
			AjaxJSONDelegate.setResponse(jAry, response);
		} catch (BusinessObjectException e) {
			e.printStackTrace();
		} catch (ServerException e) {
			e.printStackTrace();
		} catch (NetworkException e) {
			e.printStackTrace();
		}
		return null;
		// Opportunity opprtunity = new Opportunity(helper.getSession(),
		// project);

	}
}